#ifndef _BUFFER_MANAGER_
#define _BUFFER_MANAGER_

#include <ctime>
#include <fstream>
#include <queue>
#include <map>
#include <pthread.h>

using namespace std;

struct BufEntry {
	void*   pointer;
	int     nodeID;
	int		pinCounter;
	long  	last_time;
	bool	dirtyBit;
	bool	memBit;
} typedef BufTabEntry;

class BufferManager {
	public:
		BufferManager(int size, char* diskFileName);
		~BufferManager();

		bool AddEntry(void* pointer, int id);
		bool UpdateEntry(void* pointer, int id);
		bool RemoveEntry(int id);
    
		// Operation statistics updates
		void LoadUpdate(int id);
		void ReadUpdate(int id);
		void WriteUpdate(int id);
		void SaveUpdate(int id);
		
		// Allocate a new page id
		int RequestID();

		// Load from disk
		bool readFromDisk(int id, char* buffer);
		
		// Save to disk
		bool saveToDisk(int id, char* buffer);
		
		int GetIOTime() {
			return ioTime;
		};

		bool isDirty(int id);
	private:
		// Disk file
		fstream diskfile;
		
		// File lock
		pthread_mutex_t fileLock
		
		// Buffer size
		int maxSize;
		
		// Page size in bytes
		int pageSize;
		
		// Buffer
		BufTabEntry* entryArray;
		
		// Freespace
		queue<int>* freeSlot;
		
		// Map
		map<int, int>* table;
		
		// Page swapping function
		int pickEntry();
		
		// Reference time
		long ioTime;
		
		// Modified Time
		long updateTime;
		
};

#endif

